package com.example.xposedhook;

import android.util.Base64;
import android.util.Log;

import java.util.Date;

import de.robv.android.xposed.XC_MethodHook;

public class Utils {
    public static String TAG = "hlzds";

    public static void parameterLog(byte[] param,String algorithm){
        log(param,"参数列表: ",algorithm);
    }
    public static void parameterLog(byte[] param){
        log(param,"参数列表: ","");
    }

    public static void returnValueLog(byte[] param,String algorithm){
        log(param,"返回值: ",algorithm);
        partitionLine();
    }
    public static void returnValueLog(byte[] param){
        log(param,"返回值: ","");
        partitionLine();
    }

    public static void log(byte[] param,String type,String algorithm){
        String res = new String(param);
        String resHex = byteToHexString(param);
        String resB64 = Base64.encodeToString(param,0);

        try {
            logD(type);
            logD(algorithm + "  字符串形式: "+res);
            logD(algorithm + "  16进制    : "+resHex);
            logD(algorithm + "  Base64    : "+resB64);
            //   logD(algorithm + "  Url转码   : "+ URLDecoder.decode(res,"utf-8"));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void partitionLine(){
        logD("=============================================================================");
    }

    public static void logD(String msg){
        Log.d(TAG,msg);
    }

    public static byte[] object2Bytes(Object param){
        if (param instanceof Integer) {
            return intToBytes(((Integer)param).byteValue());
        } else if (param instanceof String) {
            return (byte[])param;
        } else if (param instanceof Double) {
            return (byte[])param;
        } else if (param instanceof Float) {
            return (byte[])param;
        } else if (param instanceof Long) {
            return (byte[])param;
        } else if (param instanceof Boolean) {
            return (byte[])param;
        } else if (param instanceof Date) {
            return (byte[])param;
        }
        return (byte[])param;
    }
    public static byte[] intToBytes(int i) {
        byte[] targets = new byte[4];
        targets[3] = (byte) (i & 0xFF);
        targets[2] = (byte) (i >> 8 & 0xFF);
        targets[1] = (byte) (i >> 16 & 0xFF);
        targets[0] = (byte) (i >> 24 & 0xFF);
        return targets;
    }

    public static void  printParms(XC_MethodHook.MethodHookParam param){
        Object[] args = param.args;
        int methodType = 0; //0 普通方法，1构造方法
        String methodName = "";
        if(param.method.getDeclaringClass().getName().equals(param.method.getName())){
            methodName = param.method.getName();
            methodType = 1;
        }else{
            methodName = param.method.getDeclaringClass().getName()+"."+param.method.getName();
        }
        if(args==null || args.length==0){
            logD("方法名："+methodName+"()");

        }else{
            String parmsName = "";

            for(int i=0; i<args.length; i++){
                String paramType = getType(args[i]);
                parmsName += paramType+", ";

                if(methodType == 0){//普通方法
                    if(paramType.equals("[B")) { //字节数组
                        logD("参数"+i+":"+new String((byte[])args[i]));
                    }else{
                        logD("参数"+i+":"+args[i]);
                    }
                }
            }
            parmsName = parmsName.substring(0,parmsName.length()-2);
            logD("方法名："+methodName+"("+parmsName+")");


        }

    }

    /**
     * 获取参数类型
     * @param o
     * @return
     */
    public static String getType(Object o){ //获取变量类型方法
        return o.getClass().toString().replaceAll("class ", ""); //使用int类型的getClass()方法
    }


    /**
     * byte[] 转16进制字符串
     * @param by
     * @return
     */
    public static String byteToHexString(byte[] by){
        StringBuffer sb = new StringBuffer();
        int i=0;
        while(i<by.length){
            int k=by[i];
            int j=k;
            if(k<0){
                j=k+256;
            }
            if(j<16){
                sb.append("0");
            }
            sb.append(Integer.toHexString(j));
            i ++;
        }
        return sb.toString();
    }
}
